home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / textual / txt2strg / texi2strng.pl < prev   
Perl Script  |  1995-07-02  |  21KB  |  877 lines

  1. #!/usr/local/bin/perl
  2.  
  3. # texi2strong v1.0 - © 1995 Jochen Scharrlach (jscharrl@ba-stuttgart.de)
  4.  
  5. # This program is freeware, i.e. you can freely use and distribute it.
  6. # You may not sell this program or distribute modified versions without
  7. # having the permission from the author.
  8.  
  9. # Usage: texi2strng <texinfo-file> <directory>
  10.  
  11. $RiscOS = 1;
  12.  
  13. $dirSep = "." if $RiscOS;
  14. $dirSep = "/" if ! $RiscOS;
  15.  
  16. $protectedChars = '\*\/_#<>';
  17. $refQuote = '<>=-';
  18.  
  19. $O = "\000"; # {
  20. $C = "\001"; # }
  21. $; = "\002";
  22. $B = "\003"; # \
  23. $A = "\004"; # @
  24.  
  25. %Commands = ("set", \&ComSet,
  26.              "clear", \&ComClear,
  27.              "ifclear", \&ComIfClear,
  28.              "ifset", \&ComIfSet,
  29.              "enumerate", \&ComEnumerate,
  30.              "itemize", \&ComItemize,
  31.              "item", \&ComItem,
  32.              "itemx", \&ComItem,
  33.              "end", \&ComEnd,
  34.              "example", \&ComExample,
  35.              "smallexample", \&ComExample,
  36.              "lisp", \&ComExample,
  37.              "smalllisp", \&ComExample,
  38.              "ignore", \&ComIgnore,
  39.              "titlepage", \&ComIgnore,
  40.              "tex", \&ComIgnore,
  41.              "shorttitlepage", \&DummyProc,
  42.              "c", \&DummyProc,
  43.              "comment", \&DummyProc,
  44.              "cindex", \&ComIndex,
  45.              "findex", \&ComIndex,
  46.              "vindex", \&ComIndex,
  47.              "kindex", \&ComIndex,
  48.              "pindex", \&ComIndex,
  49.              "tindex", \&ComIndex,
  50.              "iftex", \&ComIfTex,
  51.              "ifinfo", \&ComIfInfo,
  52.              "node", \&ComNode,
  53.              "bye", \&ComNode,               # write the last Node!
  54.              "page", \&ComPage,
  55.              "center", \&ComCentre,
  56.              "include", \&ComInclude,
  57.              "menu", \&ComMenu,
  58.              "synindex", \&ComSynindex,
  59.              "syncodeindex", \&ComSynindex,
  60.          "table", \&ComTable,
  61.          "vtable", \&ComTable,
  62.          "ftable", \&ComTable,
  63.          "printindex", \&ComPrintindex,
  64.          "display", \&ComDisplay,
  65.          "format", \&ComDisplay,
  66.          "flushleft", \&ComFlushleft,
  67.          "flushright", \&ComFlushright,
  68.          "quotation", \&ComQuotation,
  69.          "sp", \&ComSpace,
  70.              "deftypefn", \&ComDeftypefn,
  71.              "deftypefun", \&ComDeftypefun,
  72.              "deftypevar", \&ComDeftypevar,
  73.              "defop", \&ComDefop,
  74. #headings:
  75.             "chapter" => \&ComOneline,
  76.         "section" => \&ComOneline,
  77.         "subsection" => \&ComOneline,
  78.         "subsubsection" => \&ComOneline,
  79.         "top" => \&ComOneline,
  80.         "unnumbered" => \&ComOneline,
  81.         "unnumberedsec" => \&ComOneline,
  82.         "unnumberedsubsec" => \&ComOneline,
  83.         "unnumberedsubsubsec" => \&ComOneline,
  84.         "appendix" => \&ComOneline,
  85.         "appendixsec" => \&ComOneline,
  86.         "appendixsubsec" => \&ComOneline,
  87.         "appendixsubsubsec" => \&ComOneline,
  88.         "majorheading" => \&ComOneline,
  89.         "chapheading" => \&ComOneline,
  90.         "heading" => \&ComOneline,
  91.         "subheading" => \&ComOneline,
  92.         "subsubheading" => \&ComOneline,
  93. #those should really be ignored:
  94.           "contents", \&DummyProc,
  95.              "shortcontents", \&DummyProc,
  96.              "summarycontents", \&DummyProc,
  97.              "everyheading", \&DummyProc,
  98.              "everyfooting", \&DummyProc,
  99.              "evenheading", \&DummyProc,
  100.              "evenfooting", \&DummyProc,
  101.              "oddheading", \&DummyProc,
  102.              "oddfooting", \&DummyProc,
  103.              "heading", \&DummyProc,
  104.              "footing", \&DummyProc,
  105.              "footnotestyle", \&DummyProc,
  106.              "cartouche", \&DummyProc,
  107.              "settitle", \&DummyProc,
  108.              "setfilename", \&DummyProc,
  109.              "smallbook", \&DummyProc,
  110.              "group", \&DummyProc,
  111.              "finalout", \&DummyProc,
  112.              "setchapternewpage", \&DummyProc,
  113.              "need", \&DummyProc,
  114. #not implemented (yet):
  115.              "exdent", \&DummyProc,
  116.              "paragraphindent", \&DummyProc,
  117.              "vskip", \&DummyProc,
  118.              "noindent", \&DummyProc,
  119.              "defindex", \&WarnProc,
  120.              "defcodeindex", \&WarnProc,
  121.              "defcv", \&DummyProc,
  122.              "deffn", \&DummyProc,
  123.              "deffnx", \&DummyProc,
  124.              "defindex", \&DummyProc,
  125.              "defivar", \&DummyProc,
  126.              "defmac", \&DummyProc,
  127.              "defmethod", \&DummyProc,
  128.              "defopt", \&DummyProc,
  129.              "defspec", \&DummyProc,
  130.              "deftp", \&DummyProc,
  131.              "deftypevr", \&DummyProc,
  132.              "defvr", \&DummyProc);
  133.  
  134. @ifs = ("ifclear", "ifset", "iftex", "ifinfo");
  135.  
  136. %Oneline = ("chapter" => "{fH2}",
  137.         "section" => "{fH3}",
  138.         "subsection" => "{fH4}",
  139.         "subsubsection" => "{fH5}",
  140.         "top" => "{fH1}",
  141.         "unnumbered" => "{fH2}",
  142.         "unnumberedsec" => "{fH3}",
  143.         "unnumberedsubsec" => "{fH4}",
  144.         "unnumberedsubsubsec" => "{fH5}",
  145.         "appendix" => "{fH2}",
  146.         "appendixsec" => "{fH3}",
  147.         "appendixsubsec" => "{fH4}",
  148.         "appendixsubsubsec" => "{fH5}",
  149.         "majorheading" => "{fH1}",
  150.         "chapheading" => "{fH2}",
  151.         "heading" => "{fH3}",
  152.         "subheading" => "{fH4}",
  153.         "subsubheading" => "{fH5}");
  154. %Prefix = ("code" => $O."fCode".$C,
  155.        "kbd"  => $O."fCode".$C,
  156.        "key"  => $O."fCode".$C,
  157.         "samp" => $O."fEmphasis".$C,
  158.        "var"  => $O."fStrong".$C,
  159.        "file" => $O."fCite".$C,
  160.        "dfn"  => $O."fUnderline".$C,
  161.        "cite" => $O."fCite".$C,
  162.        "emph" => $O."fEmphasis".$C,
  163.        "strong" => $O."fStrong".$C,
  164.        "quotation" =>  $O."fCite".$C,
  165.        "sc"  => "-");
  166. %Postfix = ("code" => $O."f".$C,
  167.         "kbd" => $O."f".$C,
  168.         "key" => $O."f".$C,
  169.         "samp" => $O."f".$C,
  170.         "var" => $O."f".$C,
  171.         "file" => $O."f".$C,
  172.         "dfn" => $O."f".$C,
  173.         "cite"  => $O."f".$C,
  174.             "emph" => $O."f".$C,
  175.             "strong" => $O."f".$C,
  176.             "quotation" =>  $O."f".$C,
  177.         "sc"  => "-");
  178. %Special = ("copyright" => "©",
  179.         "bullet"    => "•",
  180.         "dots"      => "…",
  181.         "w"         => "—",
  182.         "minus"     => "-",
  183.         "result"    => "=\>",
  184.         "expansion" => "\<=\>",
  185.         "print"     => "»",
  186.         "error"     => "ERROR",
  187.         "equiv"     => "==",
  188.         "point"     => "-\>",
  189.         "TeX"       => "TeX",
  190.         "code"      => 1,
  191.         "kbd"       => 1,
  192.         "key"       => 1,
  193.         "samp"      => 1,
  194.         "var"       => 1,
  195.         "file"      => 1,
  196.         "dfn"       => 1,
  197.         "cite"      => 1,
  198.         "emph"      => 1,
  199.         "strong"    => 1,
  200.         "quotation" => 1,
  201.         "dfn"       => 1);
  202. %unknownCommands =
  203.     ("i" => 1,
  204.      "b" => 1,
  205.      "t" => 1,
  206.      "r" => 1,
  207.      "w" => 1,
  208.      "dmn" => 1);
  209. %unknownChars =
  210.     ("refill" => 1,
  211.      "i" => 1,
  212.      "b" => 1,
  213.      "t" => 1,
  214.      "r" => 1,
  215.      "w" => 1,
  216.      "dmn" => 1,
  217.      "asis" => 1);
  218. %switches = ();
  219. $currentFile = "";
  220. %File2Node = ("!Root" => "Top");
  221. %Node2File = ("Top" => "!Root",
  222.               "top" => "!Root");
  223. %Node2Menu = ();
  224. @ThisNode = ();
  225.  
  226. $ConceptIndex = {};
  227. $FunctionIndex = {};
  228. $VariableIndex = {};
  229. $KeystrokeIndex = {};
  230. $ProgramIndex = {};
  231. $DatatypeIndex = {};
  232.  
  233. %IndexCommands =
  234.     ("cindex" => \$ConceptIndex,
  235.      "findex" => \$FunctionIndex,
  236.      "vindex" => \$VariableIndex,
  237.      "kindex" => \$KeystrokeIndex,
  238.      "pindex" => \$ProgramIndex,
  239.      "tindex" => \$DatatypeIndex );
  240. %IndexRefs =
  241.     ("cp" => \$ConceptIndex,
  242.      "fn" => \$FunctionIndex,
  243.      "vr" => \$VariableIndex,
  244.      "ky" => \$KeystrokeIndex,
  245.      "pg" => \$ProgramIndex,
  246.      "tp" => \$DatatypeIndex );
  247.  
  248. $MenuFlag = 0;
  249. $ifCounter = 0;
  250. $ignoreIfCounter = 0;
  251. $ignoreIt = 1;
  252. @Dokument = ();
  253.  
  254. $unknown = 0;
  255. $numberedList = 1;
  256. $normalList = 2;
  257. $tableList = 3;
  258.  
  259. @listStack = ();
  260. $listType = $unknown;
  261. $listItemPrefix = 0;
  262.  
  263. # ****** Das Hauptprogramm:
  264.  
  265. print "Compile $ARGV[0]...\n";
  266. # open (OUT, ">$ARGV[1]/!Root") || die "Couldn't open output!\n";
  267. # $currentFile = "!Root";
  268. compileFile($ARGV[0]);
  269. close OUT;
  270.  
  271. # ****** Subroutinen:
  272.  
  273. sub compileFile {
  274.     local($file) = @_;
  275. #  local(FILE);
  276.     local($cmd, $args, $line, $stat, $block, $_, $1, $2, $3, $node);
  277.     $stat = 0;
  278.  
  279.     open (HANDLE, $file) || die "Can't open $file!\n";
  280. #  warn "File $file opened!\n";
  281.     @Dokument = <HANDLE>;
  282.     close HANDLE;
  283.  
  284.     do {
  285.     $block = "";
  286.     while (($line = shift(@Dokument)) && !($MenuFlag && $line =~ /^\*/) &&
  287.            (! ($line =~ /^@(\w+)\b/ && $Commands{$1})))
  288.     {
  289.         $block .= $line;
  290.     }
  291.  
  292.     if (!$ignoreIfCounter)
  293.     {
  294.         &output(&translate($block));
  295.     }
  296.     if ($line =~ /^@(\w+)\s*(.*)\s*$/ && $Commands{$1})
  297.     {
  298.         $cmd = $1;
  299.         $args = $2;
  300.         $args =~ s/(\S)\s+$/$1/;
  301.  
  302.         if ($ignoreIfCounter)
  303.         {
  304.         $ignoreIfCounter++ if (grep(/^$cmd$/, @ifs));
  305.         $ignoreIfCounter-- if ($cmd eq "end" && grep(/^$args$/, @ifs));
  306.         }
  307.         elsif ($Commands{$cmd} == \&ComIgnore)
  308.         {
  309.         while (($line = shift(@Dokument)) &&
  310.                !($line =~ /^\@end $cmd/ ))
  311.         {  }
  312.         }
  313.         else
  314.         {
  315. #        $args = translate($args) if $cmd ne "c";
  316.         &{$Commands{$cmd}}($cmd, translate($args)) if $Commands{$cmd} && ($cmd ne "c");
  317.         }
  318.     }
  319.     elsif ($MenuFlag && $line =~ /^\* ([^:]+)::(.*)/)
  320.     {
  321.         $cmd = translate($1);
  322.         $args = translate($2);
  323.         output(MakeRef($cmd,Ref2File($cmd)).":".$args."\n");
  324.         $Node2Menu{$cmd} = $currentNode;
  325.     }
  326.     elsif ($MenuFlag && $line =~ /^\* ([^:]+):\s*(\S[^\.]*)\.(.*)/)
  327.     {
  328.         $cmd = translate($1);
  329.         $node = translate($2);
  330.         $args = translate($3);
  331.         output(MakeRef($cmd,Ref2File($node)).":".$args."\n");
  332.         $Node2Menu{$node} = $currentNode;
  333.     }
  334.     } while ($_ = @Dokument);
  335. }
  336.  
  337. sub translate {
  338.     local($_) = @_;
  339.     local($1, $2);
  340.  
  341.     s/\@\@/$A/g;
  342.     s/\\/$B/g;
  343.  
  344.     s/\@c .*$//g;
  345.     s/\@comment .*$//g;
  346.  
  347. #    s/\\([$quoteChars])/$;$1/g;
  348.     s/\@{/$;$O/g;
  349.     s/\@}/$;$C/g;
  350.     s/\@://g;
  351.     s/\@\././g;
  352.  
  353.     s/([$protectedChars])/$;$1/g;
  354.     s/\@$;\*\n/\n# (line break)\n/g;
  355.     s/\@$;\*/\n# (line break)\n/g;
  356.  
  357.     while (s/\@(\w+){([^{}]*)}/&ComAttribute($1, $2)/eg)
  358.     { };
  359.     s/@(\w+)\b/&ComSpecial($1)/eg;    #
  360.     return rebuild($_);
  361. }
  362.  
  363. sub rebuild {
  364.     local ($_) = @_;
  365.     s/$A/\@/g;
  366.     s/$B/\\\\/g;
  367.     s/$;/\\/g;
  368.     s/$O/\{/g;
  369.     s/$C/\}/g;
  370.  
  371.     return $_;
  372. }
  373.  
  374. sub ComSet {
  375.     local($cmd, $args) = @_;
  376.  
  377.     if ($args =~ /^(\w+)\s+(.*)$/)
  378.     {
  379.     $switches{$1} = $2;
  380.     }
  381.     else
  382.     {
  383.     $switches{$args} = 1;
  384.     }
  385. }
  386. sub ComClear {
  387.     local($cmd, $args) = @_;
  388.     $switches{$args} = 0;
  389. }
  390. sub ComQuotation {
  391.     local($cmd, $args);
  392.     output("#fCite\n");
  393. }
  394. sub ComAttribute {
  395.     local($cmd, $args) = @_;
  396.  
  397.     return ComSpecial($cmd, $args) if $args eq "";
  398.     return uc($args) if $cmd eq "sc";
  399.     return $switches{$args} if $cmd eq "value";
  400.     return ComFootnote($args) if $cmd eq "footnote";
  401.     return ComXRef($cmd, $args) if $cmd eq "ref" || $cmd eq "xref" ||
  402.                                    $cmd eq "pxref" || $cmd eq "inforef";
  403.     if (!$Prefix{$cmd} && !$unknownCommands{$cmd})
  404.     {
  405.     $unknownCommands{$cmd} = 1;
  406.     warn "Command $cmd unknown!\n";
  407.     }
  408.     return $Prefix{$cmd}.$args.$Postfix{$cmd};
  409. }
  410. sub ComFootnote {
  411.     local ($text) = @_;
  412.     $noOfFootnotes++;
  413.     push (@Footnotes, "($noOfFootnotes) ".translate($text)."\n\n");
  414.  
  415.     return "{fEmphasis}($noOfFootnotes){f}";
  416. }
  417. sub ComSpecial {
  418.     local($cmd) = @_;
  419.  
  420.     if (!$Special{$cmd} && !$unknownChars{$cmd})
  421.     {
  422.     $unknownChars{$cmd} = 1;
  423.     warn "Special character $cmd unknown!";
  424.         warn "  next line: $Dokument[0]";
  425.     }
  426.     if ($Special{$cmd} == 1)
  427.     {
  428.     return $Prefix{$cmd};
  429.     }
  430.     else
  431.     {
  432.     return $Special{$cmd};
  433.     }
  434. }
  435. sub ComIfSet {
  436.     local($cmd, $args) = @_;
  437.     if ($switches{$args})
  438.     {
  439.     $ifCounter++;
  440.     }
  441.     else
  442.     {
  443.     $ignoreIfCounter++;
  444.     }
  445. }
  446. sub ComIfClear {
  447.     local($cmd, $args) = @_;
  448.     if (!$switches{$args})
  449.     {
  450.     $ifCounter++;
  451.     }
  452.     else
  453.     {
  454.     $ignoreIfCounter++;
  455.     }
  456. }
  457. sub ComIfTex {
  458.     local($cmd, $args) = @_;
  459.     $ignoreIfCounter++;
  460. }
  461. sub ComIfInfo {
  462.     local($cmd, $args) = @_;
  463.     $ifCounter++;
  464. }
  465. sub ComEnumerate {
  466.     local($cmd, $args) = @_;
  467.     push (@listStack, [$listType, $listItemPrefix, $listItemIndex]);
  468.     $listType = $numberedList;
  469.     $listItemPrefix = $args;
  470.     $listItemPrefix = 1 if $args eq "";
  471.     $listItemIndex = 0;
  472.     output ("#Indent +4\n");
  473. }
  474. sub ComItemize {
  475.     local($cmd, $args) = @_;
  476.     push (@listStack, [$listType, $listItemPrefix, $listItemIndex]);
  477.     $listType = $normalList;
  478.     $listItemPrefix = $args;
  479.     $listItemIndex = 0;
  480.     output ("#Indent +4\n");
  481. }
  482. sub ComTable {
  483.     local($cmd, $args) = @_;
  484.     push (@listStack, [$listType, $listItemPrefix, $listItemIndex]);
  485.     $listType = $tableList;
  486.     $listItemPrefix = $args;
  487.     if ($cmd eq "ftable")
  488.     {
  489.     $listItemIndex = \$FunctionIndex;
  490.     }
  491.     elsif ($cmd eq "vtable")
  492.     {
  493.     $listItemIndex = \$VariableIndex;
  494.     }
  495.     else
  496.     {
  497.     $listItemIndex = 0;
  498.     }
  499.     output ("#Indent +4\n");
  500. }
  501. sub ComItem {
  502.     local($cmd, $args) = @_;
  503.  
  504. #    output ("\n") if $cmd eq "item";
  505.  
  506.     if ($listType == $numberedList)
  507.     {
  508.     output(" $listItemPrefix. ");
  509.     $listItemPrefix++;
  510.     }
  511.     elsif ($listType == $tableList)
  512.     {
  513.     if ($listItemPrefix =~ /^{/)
  514.     {
  515.         output("#Indent\n".$listItemPrefix.$args."{f}\n#Indent +4\n");
  516.     }
  517.     else
  518.     {
  519.         output("#Indent\n$listItemPrefix$args\n#Indent +4\n");
  520.     }
  521.     IndexInsert($listItemIndex, $args) if $listItemIndex;
  522.     }
  523.     else
  524.     {
  525.     output("\n $listItemPrefix ");
  526.     }
  527. }
  528. sub IndexInsert {
  529.     ($i, $a) = @_;
  530.     $a =  RemoveAttributes($a);
  531.     $$i->{$a} = $currentFile if ! $$i->{$a};
  532. }
  533. sub ComExample {
  534.     local($cmd, $args) = @_;
  535.     output ("#Wrap off\n#fCode\n");
  536. }
  537. sub ComDisplay {
  538.     local($cmd, $args) = @_;
  539.     output ("#Wrap off\n");
  540. }
  541. sub ComIgnore {
  542.     local($cmd, $args) = @_;
  543.     $ignoreIt = 1;
  544. }
  545. sub ComC {
  546.     local($cmd, $args) = @_;
  547.     output ("# $args\n");
  548. }
  549. sub ComIndex {
  550.     local($cmd, $args) = @_;
  551.     local($hash);
  552.  
  553.     if (!($hash = $IndexCommands{$cmd}))
  554.     {
  555.     warn "Unknown index command: $cmd\n";
  556.     return;
  557.     }
  558. #    warn "Index: $cmd $args\n";
  559.     $hash = $$hash;
  560.     $args = RemoveAttributes(rebuild($args));
  561.     $hash->{$args} = $currentFile if ! $hash->{$args};
  562. }
  563. sub ComSynindex {
  564.     local($cmd, $args) = @_;
  565.     local($fromhash, $tohash, $_, $1, $2);
  566.  
  567.     $_ = $args;
  568.  
  569.     if (! /^\s*(\w+)\s+(\w+)\s*$/)
  570.     {
  571.     warn "Wrong syncodeindex-syntax: $args\n";
  572.     return;
  573.     }
  574.     $fromhash = $IndexRefs{$1};
  575.     $tohash = $IndexRefs{$2};
  576.  
  577.     if (!($fromhash && $tohash))
  578.     {
  579.     warn "Unknown index commands: >$1< >$2<\n";
  580.     return;
  581.     }
  582.     $$fromhash = $$tohash;
  583. }
  584. sub ComPrintindex {
  585.     local($cmd, $args) = @_;
  586.     local($_, $hash);
  587.     if (!($hash = $IndexRefs{$args}))
  588.     {
  589.     warn "Index %args unknown!\n";
  590.     return;
  591.     }
  592.     $hash = $$hash;
  593.     output ("#Wrap off\n");
  594.     for (sort(keys %$hash))
  595.     {
  596.     output(MakeRef($_,$hash->{$_})."\n");
  597.     }
  598.     output ("#Wrap on\n");
  599. }
  600.  
  601. sub ComOneline {
  602.     local($cmd, $args) = @_;
  603.  
  604.     output ($Oneline{$cmd}.$args."{f}\n");
  605. }
  606. sub ComPage {
  607.     local($cmd, $args) = @_;
  608.     output ("#Line\n");
  609. }
  610. sub ComNode {
  611.     local($cmd, $args) = @_;
  612.     local($panel, $holdPrev);
  613.     local(@par);
  614.  
  615.     @par = split(/\s*,\s*/, $args);
  616.     if ($currentFile)
  617.     {
  618.         $nextNode = $par[0] if $nextNode eq "";
  619.     $ThisNode[1] = "Previous: <".$prevNode."=>".Ref2File($prevNode)."> * "
  620.                if $prevNode ne "";
  621.     $ThisNode[1] .= "Next: <".$nextNode."=>".Ref2File($nextNode)."> * "
  622.            if $nextNode ne "";
  623.     $ThisNode[1] .= "Up: <".$upNode."=>".Ref2File($upNode).">"
  624.            if $upNode ne "";
  625.         $ThisNode[1] .= "\n\n";
  626.  
  627.         open(OUT, ">".$ARGV[1].$dirSep.$currentFile)
  628.         || die "Couldn't open $currentFile!\n";
  629.  
  630.         print OUT @ThisNode;
  631.     if ($noOfFootnotes)
  632.     {
  633.         print OUT "#Line\n";
  634.         print OUT @Footnotes;
  635.     }
  636.         close OUT;
  637.     }
  638.     $holdPrev = $currentNode;
  639.     ($currentNode, $nextNode, $prevNode, $upNode) = @par;
  640.     $prevNode = $holdPrev if $prevNode eq "";
  641.     $upNode = $Node2Menu{$currentNode} if $upNode eq "";
  642.  
  643.     @ThisNode = ("$currentNode\n", "", "#Wrap on\n");
  644.     $currentFile = Ref2File($currentNode);
  645.     $noOfFootnotes = 0;
  646.     @Footnotes = ();
  647. }
  648. sub ComSetTitle {
  649.     local($cmd, $args) = @_;
  650.     # tja, ne Node halt...
  651. }
  652. sub ComSetFileName {
  653.     local($cmd, $args) = @_;
  654.     # tja, ne Node halt...
  655. }
  656. sub DummyProc {
  657.     local($cmd, $args) = @_;
  658. #    warn "Warning: $cmd not supported!!\n";
  659. }
  660. sub ComEmph {
  661.     local($cmd, $args) = @_;
  662.     output ("\n{fEmphasis} $args {f}\n");
  663. }
  664. sub ComCentre {
  665.     local($cmd, $args) = @_;
  666.     output ("#Align Centre\n$args\n#Align\n");
  667. }
  668. sub ComFlushleft {
  669.     local($cmd, $args) = @_;
  670.     output ("#Align left\n");
  671. }
  672. sub ComFlushright {
  673.     local($cmd, $args) = @_;
  674.     output ("#Align right\n");
  675. }
  676. sub ComMenu {
  677.     local($cmd, $args) = @_;
  678.     $MenuFlag = 1;
  679.     output ("#Wrap off\n");
  680. }
  681. sub ComDeftypefn {
  682.     local($cmd, $_) = @_;
  683.     local(@a, $c, $t, $n);
  684.     
  685.     ($c, $t, $n, @a) = ParseArgs($_, 3);
  686.     output(ucfirst($c).": $t $n @a\n#Indent +4\n");
  687.     IndexInsert(\$FunctionIndex, $n);
  688. }
  689. sub ComDeftypefun {
  690.     local($cmd, $_) = @_;
  691.     local(@a, $c, $t);
  692.     
  693.     ($t, $n, @a) = ParseArgs($_, 2);
  694.     output("Function: $t $n @a\n#Indent +4\n");
  695.     IndexInsert(\$FunctionIndex, $n);
  696. }
  697. sub ComDeftypevar {
  698.     local($cmd, $_) = @_;
  699.     local(@a);
  700.     
  701.     ($t, $n, @a) = ParseArgs($_, 2);
  702.     output("Variable: $t $n @a\n#Indent +4\n");
  703.     IndexInsert(\$VariableIndex, $n);
  704. }
  705. sub ComDefop {
  706.     local($cmd, $_) = @_;
  707.     local(@a, $c, $t, $n);
  708.  
  709.     ($c, $t, $n, @a) = ParseArgs($_, 3);
  710.     output(ucfirst($c).": $t::$n @a\n#Indent +4\n");
  711.     IndexInsert(\$FunctionIndex, $n." on ".$t);
  712. }
  713. sub ParseArgs {
  714.     local($line, $i) = @_;
  715.     local(@a, $1, $2);
  716.  
  717.     @a = ();
  718.     $2 = "";
  719.     
  720.     while ($line ne "" && ($line =~ /^\s*{([^{}]*)}(.*)$/ ||
  721.                            $line =~ /^\s*(\S+) (.*)$/ ||
  722.                            $line =~ /^\s*(\S+)$/) && $i > 0)
  723.     {
  724.         push (@a, $1);
  725.         $line = $2;
  726.         $2 = "";
  727.         $i--;
  728.     }
  729.     return (@a, $line);
  730. }
  731.         
  732. sub ComEnd {
  733.     local($cmd,$args) = @_;
  734.  
  735.     if (grep(/^$args$/, @ifs))
  736.     {
  737.     $ifCounter--;
  738.     }
  739.     elsif ($args eq "itemize" || $args eq "enumerate" ||
  740.        $args eq "table" || $args eq "ftable" || $args eq "vtable")
  741.     {
  742.     ($listType, $listItemPrefix, $listItemIndex) = @{pop(@listStack)};
  743.     output ("\n#Indent\n");
  744.     }
  745.     elsif ($args eq "example" || $args eq "smallexample" ||
  746.            $args eq "lisp" || $args eq "smalllisp")
  747.     {
  748.     output ("#f\n#Wrap on\n");
  749.     }
  750.     elsif ($args eq "menu")
  751.     {
  752.     $MenuFlag = 0;
  753.         output ("#Wrap on\n");
  754.     }
  755.     elsif ($args eq "display" ||$args eq "format")
  756.     {
  757.         output ("#Wrap on\n");
  758.     }
  759.     elsif ($args eq "flushleft" ||$args eq "flushright")
  760.     {
  761.         output ("#Align\n");
  762.     }
  763.     elsif ($args eq "quotation")
  764.     {
  765.         output ("#f\n");
  766.     }
  767.     elsif ($args eq "deftypefn" || $args eq "deftypefun" ||
  768.            $args eq "deftypevar" || $args eq "defop")
  769.     {
  770.         output ("#Indent\n");
  771.     }
  772.     elsif ($args eq "group" || $args eq "cartouche")
  773.     {
  774.     # don't care
  775.     }
  776.     else
  777.     {
  778.       warn "Unknown end sequence: $args\n";
  779.     }
  780. }
  781. sub ComInclude {
  782.     local($cmd,$args) = @_;
  783.     local(@help);
  784.     $args =~ s/\./\//g if $RiscOS;
  785.     open (HANDLE, $args) || die "Can't open $args\n";
  786.     @help = <HANDLE>;
  787.     close HANDLE;
  788.     @Dokument = (@help, @Dokument);
  789. }
  790. sub ComXRef {
  791.     local ($cmd, $_) = @_;
  792.     local ($node, $cross, $topic, $text, @args);
  793.  
  794.     s/\n/ /g;
  795.  
  796.     ($node, $cross, $text) = split(/\s*,\s*/, $_);
  797.     $cross = $node if $cross eq "";
  798.     $text = ": $text" if $text ne "";
  799.  
  800. #    warn "Converted: $_ -> <$label=>$file>";
  801.     $node = Ref2File($node);
  802.     $cross = RemoveInternalAttributes($cross);
  803.     return "\\*Note <$cross=>$node>$text";
  804. }
  805. sub ComSpace {
  806.     local($cmd, $args) = @_;
  807.     for (1 .. $args)
  808.     {
  809.         output ("\n");
  810.     }
  811. }
  812. sub RemoveInternalAttributes {
  813.     local($_) = @_;
  814.  
  815.     s/$;$O/\\{/g;
  816.     s/$;$C/\\}/g;
  817.     s/$O[^$O$C]*$C//g;
  818.     s/\\{/$;$O/g;
  819.     s/\\}/$;$C/g;
  820.     return $_;
  821. }
  822. sub RemoveAttributes {
  823.     local($_) = @_;
  824.  
  825.     s/\\{/$;$O/g;
  826.     s/\\}/$;$C/g;
  827.     s/{[^{}]*}//g;
  828.     s/$;$O/\\{/g;
  829.     s/$;$C/\\}/g;
  830.     return $_;
  831. }
  832. sub translateNode {
  833.     local ($_) = @_;
  834.     s/[\W]//g;
  835.     return (substr($_, 0, 10));
  836. }
  837. sub MakeRef {
  838.     local ($ref, $node) = @_;
  839.     if ($ref =~ /^[$refQuote]/)
  840.     {
  841.       return "<\\".$ref."=>".$node.">";
  842.     }
  843.     else
  844.     {
  845.       return "<".$ref."=>".$node.">";
  846.     }
  847. }
  848. sub Ref2File {
  849.     local ($_) = @_;
  850.     local ($f);
  851.  
  852. #    s/{[^}]*}//g;
  853.  
  854.     if ( $Node2File{$_} ne "")
  855.     {
  856.     return $Node2File{$_};
  857.     }
  858.     else
  859.     {
  860.     $f = translateNode($_);
  861.     $f = "A" if $f eq "";
  862.     while ($File2Node{$f})
  863.     {
  864.         $f++;
  865.     }
  866.     $File2Node{$f} = $_;
  867.     $Node2File{$_} = $f;
  868. #    warn "translated: $_ -> $f\n";
  869.     return $f;
  870.     }
  871. }
  872. sub output {
  873.     local($line) = @_;
  874.     push @ThisNode, $line;
  875. }
  876.  
  877.